package com.hmdp.utils;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

/**
 * redis的id生成器,通过记录时间戳和序列号来生成唯一的ID
 * 1.获取当前时间，并将其转换为基于UTC时间的秒数。
 * 2.利用Redis的自增操作生成序列号，同时将序列号与当前日期相关联。
 * 3.最后，根据时间戳和序列号，拼接成一个唯一的ID，并返回。当前代码中，返回0L的部分未实现，应根据实际需求进行完善。
 */
@Component
public class RedisIdWorker {
    //开始时间戳
    private static final long BEGIN_TIMESTS = 164099520000L;

    //序列号的位数
    private static final int COUNT_BITS = 32;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    // 生成下一个ID
    public long nextId(String keyPrefix) {
        // 1.生成时间戳
        LocalDateTime now = LocalDateTime.now(); // 获取当前时间
        long nowSecond = now.toEpochSecond(ZoneOffset.UTC); // 转换为秒数，基于UTC时间
        long timestamp = nowSecond - BEGIN_TIMESTS; // 计算时间戳

        // 2.生成序列号,利用redis的自增长
        // 2.1获取当前日期，精确到天
        String date= now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd")); // 格式化当前日期为yyyy:MM:dd形式
        long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date); // 通过Redis自增操作生成序列号

        // 3.拼接并返回,将时间戳左移 COUNT_BITS 位，然后使用按位或操作符 | 将其与计数值（count）组合在一起，形成一个唯一的 ID
        return timestamp << COUNT_BITS | count;
    }
}
